package pl.edu.mimuw.irs.core.model.design.net;

import java.util.List;

import pl.edu.mimuw.irs.core.model.design.exception.InternalDesignException;
import pl.edu.mimuw.irs.core.model.design.net.refinement.IRSAbstractChildren;
import pl.edu.mimuw.irs.core.model.design.net.refinement.Refinement;
import pl.edu.mimuw.irs.core.model.petrinet.INode;
import pl.edu.mimuw.irs.core.util.IPropertyContainer;
import pl.edu.mimuw.irs.core.util.Position;

/**
 * @author Jakub Rauch
 * Created on: 2009-05-09
 */
public interface IRSNode extends INode, IPropertyContainer {

	// *** Properties
	
	public static final String CHILDREN = "children";
	public static final String EXPANDED = "expanded";
	public static final String VISIBLE = "visible";
	
	// *** Attributes

	// Getters and setters
	/** Returns the current refinement pattern of this node. */
	public Refinement getRefinement();
	/** Applies the given refinement pattern to this node. */
	public void refine(Refinement refinement);
	/** Returns the children of this node. */
	public IRSAbstractChildren getChildren();
	/** Returns the parent of this node. */
	public IRSNode getParent();
	/** Sets the new parent of this node. */
	public void setParent(IRSNode parent);
	/** Returns the automatically generated position of this node. */
	public Position getSuperPosition();
	/** Returns the manually set position of this node. */
	public Position getCustomPosition();
	/** Changes the manually set position of this node. */
	public void setCustomPosition(Position position);
	/** Copies all the contents (deep) of the given node to this one. */
	/** Tells whether this node is currently expanded or not. */
	public boolean isExpanded();
	/** Sets this node to expanded or collapsed state. */
	public void setExpanded(boolean expand);
	
	//public boolean isAtomic();
	//public AtomicSubnet getAtomicWorkflow(AtomicSubnet subnet);
	//public List<IRSArc> getAtomicIncomingArcs();
	//public List<IRSArc> getAtomicOutgoingArcs();
	/** Tells whether the node has been detached or not. */
	public boolean isDetached();
	
	// *** Methods

	/** Tells whether this node is an ancestor of the node given or not. */
	public boolean isAncestorOf(IRSNode node);
	/** Checks if this node is a root - has no parents. */
	public boolean isRoot();
	/** Checks if this node is a leaf - has no children. */
	public boolean isLeaf();
	/** Checks if this node is currently at visible level (checks if all ancestor nodes are expanded). */
	public boolean isVisible();
	///** Returns all leaf nodes from this one. */
	//public List<IRSNode> getAtomicNodes();
	/** Returns non expanded descendants of expanded nodes or leafs. In other words these are the visible nodes under
	 * this one (if this one is expanded - otherwise it will be this node only). */
	public List<IRSNode> getVisibleNodes();
	///** Creates copy of this node and all descendants as well as arcs between them.
	// * @return copied node */
	//public IRSNode copy();
	///** Creates copy of this node and all descendants as well as arcs between them.
	// * @return copied node */
	//public IRSNodeCopier getCopier();
	///**
	// * Creates copy of this node - only a clean copy of this
	// * node for the atomic subnet purposes. The data
	// * will be attached to the copied node in getAtomicSubnet() method.
	// * This method should be protected but is made public to force
	// * its creation on every node.
	// * @return copied node
	// */
	//public INode copy(AtomicSubnet subnet);
	/** Connects this node to the other. It handles connecting recursively (by connecting input and output children
	 * respectively) on the contained children. Petri nets prohibit connecting nodes of the same type, and violation
	 * of this rule will cause an {@link InternalDesignException} to be thrown. */
	public void connect(IRSNode node);
	/** Disconnects this node from all other elements */
	public void detach();
	/** Method for cloning concrete nodes. By convention it should just invoke the copying constructor of this class. */
	public IRSNode clone();
}
